package List;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

/**
 * @Author:Cjj
 * 进程：
 *  是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程
 *  在java中,当我们启动main函数时其实就是启动一个JVM的进程,而main函数所在的线程就是这个进程中的一个线程,也称主线程。
 * 线程：
 *  线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享进程
 *  的堆和方法区资源,但每个线程有自己的程序计数器,虚拟机栈和本地方法栈,所以系统在产生一个线程，或是在各个线程之间做切换工作时，负担要比
 *  进程小得多,也正因为如此,线程也被称为轻量级进程。
 */
public class MultiThread {
    public static void main(String[] args) {
        //获取Java线程管理MXBean
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        //不需要获取同步的monitor和synchronizer信息,仅获取线程和线程堆栈信息
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
        //遍历线程信息,仅打印线程ID和线程名称信息
        for (ThreadInfo threadInfo : threadInfos) {
            System.out.println("[" + threadInfo.getThreadId() + "]" + threadInfo.getThreadName());
        }
    }

    /**
     * java线程和操作系统的线程有啥区别？
     *JDK1.2之前,java线程是基于绿色线程实现的，这是一种用户级线程,也就是说JVM自己模拟了多线程的运行。而不依赖于操作系统。
     * 由于绿色线程和原生线程比起来在使用时有一些限制,在JDK1.2及以后，Java线程改为基于原生线程实现,也就是说JVM直接使用操作系统
     * 原生的内核级线程(内核线程)来实现Java线程,由操作系统内核进行线程的调度和管理。
     *
     * 用户线程：由用户空间程序管理和调度的线程，运行在用户空间(专门给应用程序使用)。
     * 内核线程：由操作系统内核管理和调度的线程,运行在内核空间(只有内核程序可以访问)。
     *
     * 1.一对一(一个用户线程对应一个内核线程)
     * 2.多对一(多个用户线程映射到一个内核线程)
     * 3.多对多(多个用户线程映射到多个内核线程)
     *
     * 在windows和Linux等主流操作系统中,Java线程采用的是一对一的线程模型,也就是一个Java线程对应一个系统内核线程。
     * 一个进程中可以有多个线程,多个线程共享进程的堆和方法区资源,但是每个线程有自己的程序计数器,虚拟机和本地方法栈。
     * 总结：线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而个线程则不一定，因为同一
     * 进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护；而进程正相反。
     * 程序计数器为什么是私有的？
     *  1.字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如：顺序执行,选择,循环,异常处理。
     *  2.在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪里了。
     */

    /**
     * 虚拟机栈和本地方法栈为什么是私有的?
     * 虚拟机栈：每个Java方法在执行之前会创建一个栈帧用于存储局部变量表,操作数栈,常量池引用等信息。从方法调用直至执行完成的过程，
     * 本地方法栈：和虚拟机栈所发挥的作用非常相似,区别是：虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到
     * 的Native方法服务。所以,为了保证线程中的局部变量不被别的线程访问到,虚拟机栈和本地方法是线程私有的。
     *
     * 一句话简单了解堆和方法区
     *  堆和方法区是所有线程共享的资源,其中堆是进程中最大的一块内存，主要用于存放新创建的对象(几乎所有对象都在这里分配内存),方法区
     *  主要用于存放已被加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。
     *
     *  如何创建线程？
     *  一般来说,创建线程有很多种方式,例如继承Thread类,实现Runnable接口,实现Callable接口,使用线程池,使用CompletableFuture等。
     *  不过,这些方式其实并没有真正创建出线程。准确点来说,这些都属于是在Java代码中使用多线程的方法。
     */

}
